// ignore_for_file: file_names, must_be_immutable, constant_identifier_names, slash_for_doc_comments, avoid_unnecessary_containers, prefer_const_constructors, unnecessary_cast, sized_box_for_whitespace, prefer_function_declarations_over_variables, overridden_fields, annotate_overrides, prefer_const_literals_to_create_immutables, unnecessary_null_comparison, deprecated_member_use
import 'package:flutter/foundation.dart';
import 'package:flutter_web_server/ImcludeServer.dart';
import 'package:flutter_web_server/entity/ServerInfo.dart';
import 'package:flutter_web_server/util/ServerFileHelp.dart';
import 'package:flutter_web_server/util/ServerHelp.dart';
import 'package:mybase/base/tool/pprint/FFLog.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;

class ServerManager {
  // 单例公开访问点
  factory ServerManager() => _sharedInstance();

  // 静态、同步、私有访问点
  static ServerManager _sharedInstance() {
    return _instance;
  }

  // 静态私有成员，没有初始化
  static final ServerManager _instance = ServerManager._();

  // 私有构造函数
  ServerManager._() {}

  /// 停止服务
  stop({
    required ServerInfo? serverInfo,
  }) {
    if (serverInfo == null) return;
    serverInfo.server?.close(force: true);
    serverInfo.server = null;
  }

  /**
   * 启动服务
   * [isHasWeb] 是否启动web项目, web.zip文件请放在根目录下的assets/web.zip
   * [isLaunchRemoveCache] 是否启动清除缓存,只对debug有效
   * [maxUploadSize] 最大上传大小,默认1G
   * [onRegisterRouter] 注册路由
   *    router.get("/snjj", (Request request) {
      return ServerR(msg: "Hello snjj").toOK();
      });

   */
  Future<ServerInfo?> start({
    bool isHasWeb = false,
    bool isLaunchRemoveCache = true,
    int? maxUploadSize = 1024 * 1024 * 10 * 100, // 10M * 100
    Function(Router router)? onRegisterRouter,
    String? ip,
    int? port,
    String document = "",
    String fileDirName = "downfile",
    String? certPem,
    String? priKeyPem,
  }) async {

    // 复制文件到沙盒
    String? indexPath;
    if (isHasWeb) indexPath = await ServerFileHelp.copyFileFromAssets(isLaunchRemoveCache: isLaunchRemoveCache);
    if (FFEmpty.stringIsEmpty(indexPath) && isHasWeb) {
      assert(false, "isHasWeb=true时，web.zip文件请放在根目录下的assets/web.zip");
      return null;
    }

    // 获取本机IP和端口
    int? localPort = port ?? await ServerHelp.getAvailablePort();
    ip ??= await ServerHelp.getLocalIpAddress();
    if (localPort == null) {
      return null;
    }

    // 创建路由
    var router = Router();

    // 注册路由，在外部注册
    onRegisterRouter?.call(router);

    Map<String, String>? overrideHeaders;
    if (isHasWeb) {
      // 创建静态文件处理,内置web项目
      overrideHeaders = ServerFileHelp.createStaticWeb(
        indexPath: indexPath!,
        router: router,
      );
    }

    var staticHandler = createStaticHandler(document, defaultDocument: 'index.html');

    // 创建管道
    var pipeline = Pipeline();

    // 中间件
    pipeline = pipeline.addMiddleware(corsHeaders(headers: overrideHeaders));
    pipeline = pipeline.addMiddleware(logRequests());

    // 使用Pipeline添加中间件和路由
    var handler = pipeline.addHandler((Request request) async {
      if (request.url.path.startsWith(fileDirName)) {
        // 资源下载
        return staticHandler(request);
      }
      // 路由请求
      return router.call(request);
    });

    // 使用 HTTPS 启动服务器
    SecurityContext? securityContext;
    if (certPem != null && priKeyPem != null) {
      securityContext = SecurityContext()
        ..useCertificateChain(certPem)
        ..usePrivateKey(priKeyPem);
    }

    // 启动服务器
    var server = await shelf_io.serve(
      handler,
      ip ?? '0.0.0.0',
      localPort,
      securityContext: securityContext,
    );
    FFLog.info("服务器开启成功 $ip:${server.port}");
    return ServerInfo(
      server: server,
      ip: ip,
      port: server.port,
    );
  }
}
